<?php
class Dmf_Collection implements Iterator
{
    /**
     * All data
     * 
     * @var array 
     */
    private $_data = array();
    
    /**
     * Constructor
     * 
     * @param array $data 
     */
    public function __construct( $data = array() )
    {
        if ( $data instanceof Dmf_Stdclass )
        {
            $data = $data->asArray();
        }
        
        if ( ! is_array( $data ) )
        {
            $data = func_get_args();
        }
        
        $this->_data = $data;
    }
    
    /**
     * Get value
     * 
     * @param string $index
     * @return mixed
     */
    public function __get( $index )
    {
        return isset( $this->_data[ $index ] ) ? $this->_data[ $index ] : null;
    }
    
    /**
     * Add item to collection
     * 
     * @param mixed $item 
     * @param mixed $val
     */
    public function add( $item, $val = null )
    {
        if ( $val === null )
        {
            $this->_data[] = $item;
        }
        else
        {
            $this->_data[ $item ] = $val;
        }
    }
    
    /**
     * Item to remove
     * 
     * @param mixed $item 
     */
    public function remove( $item )
    {
        if ( is_array( $item ) )
        {
            foreach( $item as $sub )
            {
                $this->remove( $sub );
            }
            
            return;
        }
        
        unset( $this->_data[ $this->find( $item ) ] );
    }
    
    /**
     * Get range in collection
     * 
     * @param mixed $from
     * @param mixed $to
     * @return Dmf_Collection 
     */
    public function range( $from, $to = false )
    {
        if ( $to === false ) $to = ( count( $this->_data ) - 1 );
        if ( ! is_numeric( $from ) ) $from = $this->find( $from );
        if ( ! is_numeric( $to ) ) $to = $this->find( $to );
        if ( $from < 0 ) $from = ( count( $this->_data ) - 1 ) + $from;
        if ( $to < 0 ) $to = ( count( $this->_data ) - 1 ) + $to;
        
        $collection = new Dmf_Collection;
        
        for ( $i = 0; $i < count( $this->_data ); ++$i )
        {
            if ( $i >= $from && $i <= $to )
            {
                $collection->add( $this->_data[ $i ] );
            }
        }
        
        return $collection;
    }
    
    /**
     * Find item in collection
     * 
     * @param mixed $item
     * @param array|null $array
     * @return boolean 
     */
    public function find( $item, $array = null )
    {
        foreach( ( is_array( $array ) ? $array : $this->_data ) as $key => $val )
        {
            if ( is_array( $val ) )
            {
                if ( ( $found = $this->find( $item, $val ) ) !== false )
                {
                    return $found;
                }
            }
            
            if ( $key == $item || $val == $item )
            {
                return $key;
            }
        }
        
        return false;
    }
    
    /**
     * Implementing the default rewind function 
     */
    public function rewind()
    {
        reset( $this->_data );
    }
    
    /**
     * Implementing the default current function
     * 
     * @return Dmf_Database_Table 
     */
    public function current()
    {
        return current( $this->_data );
    }
    
    /**
     * Implementing the default key function
     * 
     * @return string
     */
    public function key()
    {
        return key( $this->_data );
    }
    
    /**
     * Implementing the default next function
     * 
     * @return Dmf_Database_Table
     */
    public function next()
    {
        return next( $this->_data );
    }
    
    /**
     * Implementing the default valid function
     * 
     * @return Dmf_Database_Table
     */
    public function valid()
    {
        $key = key( $this->_data );
        
        return ( $key !== null && $key !== false );
    }
}